package com.itasura.guava.Concurrency;

import com.google.common.util.concurrent.*;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.*;

/**
 * @author sailor wang
 * @date 2018/10/30 12:03 PM
 * @description
 */
@Slf4j
public class ListenableFutureTest {

    @Test
    public void futureTest() throws ExecutionException, InterruptedException {
        //不提倡这种方式创建线程池，用ThreadPoolExecutor
        ExecutorService es = Executors.newCachedThreadPool();
        Future<String> future = es.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return SimpleService.visitDb();
            }
        });
        String result = future.get();
        log.info("result -> {}", result);
    }

    @Test
    public void futureWithTimeoutTest() throws InterruptedException, ExecutionException, TimeoutException {
        //不提倡这种方式创建线程池，用ThreadPoolExecutor
        ExecutorService es = Executors.newCachedThreadPool();
        Future<String> future = es.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return SimpleService.visitBlockDb();
            }
        });
//        String result = future.get(2, TimeUnit.SECONDS);
        String result = future.get(3, TimeUnit.SECONDS);
        log.info("result -> {}", result);
    }

    @Test
    public void listenableFutureTest() {
        ListeningExecutorService es = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(3));
        ListenableFuture listenableFuture = es.submit(new Callable<String>() {

            /**
             * Computes a result, or throws an exception if unable to do so.
             *
             * @return computed result
             * @throws Exception if unable to compute a result
             */
            @Override
            public String call() throws Exception {
                //return SimpleService.visitDb();
                return SimpleService.visitDbFail();
            }
        });
        Futures.addCallback(listenableFuture, new FutureCallback<String>() {
            @Override
            //Future成功的时候执行，根据Future结果来判断
            public void onSuccess(String v) {
                log.info("调用成功");
            }

            @Override
            //Future失败的时候执行，根据Future结果来判断
            public void onFailure(Throwable throwable) {
                log.info("调用失败");
            }
        });
    }


}